using System;
using System.Collections.Generic;

namespace Rel.Expressions
{
    public abstract partial class RegBase
    {
        #region Extracts

        public RegBase ExtractCollection(string extractName, RelGroup externalPattern, RelGroup elementPattern)
        {
            return new ExtractCollection(extractName, externalPattern, elementPattern, this.Parent);
        }

        public RegBase Extract(string extractName, RelGroup internalPattern)
        {
            return new Extract(extractName, internalPattern, this.Parent);
        }

        #endregion

        #region Character Classes
        /// <summary>
        /// Defines a literal as part of the pattern
        /// </summary>
        /// <param name="s">S.</param>
        public RegBase Literal(string s)
        {
            return new Literal(s, this.Parent);
        }

        /// <summary>
        /// Defines an alphabet character as part of the pattern.
        /// </summary>
        public RegBase Alphabet()
        {
            return new Alphabet(this.Parent);
        }

        /// <summary>
        /// Defines anything except a newline character as part of the pattern.
        /// </summary>
        /// <returns>The except newline.</returns>
        public RegBase AnyExceptNewline()
        {
            return new AnyExceptNewline(this.Parent);
        }

        /// <summary>
        /// Matches any character in the string as part of the pattern.
        /// </summary>
        /// <returns>The matches.</returns>
        /// <param name="characters">Characters.</param>
        public RegBase CharacterMatches(string characters)
        {
            return new CharacterMatches(characters, this.Parent);
        }

        /// <summary>
        /// Matches decimal characters.
        /// </summary>
        public RegBase Decimal()
        {
            return new DecimalMatcher(this.Parent);
        }

        /// <summary>
        /// Defines a no character matches expression on all characters in the string.
        /// </summary>
        /// <returns>The character matches.</returns>
        /// <param name="s">S.</param>
        public RegBase NoCharacterMatches(string s)
        {
            return new NoCharacterMatches(s, this.Parent);
        }

        /// <summary>
        /// Matches non decimal characters.
        /// </summary>
        /// <returns>The decimal.</returns>

        public RegBase NonDecimal()
        {
            return new NonDecimal(this.Parent);
        }

        /// <summary>
        /// Matches non whitespace characters.
        /// </summary>
        /// <returns>The whitespace.</returns>
        public RegBase NonWhitespace()
        {
            return new NonWhitespace(this.Parent);
        }

        /// <summary>
        /// Matches non word characters.
        /// </summary>
        /// <returns>The word character.</returns>
        public RegBase NonWordCharacter()
        {
            return new NonWordCharacter(this.Parent);
        }

        /// <summary>
        /// Matches whitespace characters.
        /// </summary>
        public RegBase Whitespace()
        {
            return new WhiteSpace(this.Parent);
        }

        /// <summary>
        /// Matches word characters.
        /// </summary>
        /// <returns>The character.</returns>
        public RegBase WordCharacter()
        {
            return new WordCharacter(this.Parent);
        }

        #endregion

        #region Grouping and Special
        /// <summary>
        /// Performs an OR operation on two or more expression chains.
        /// </summary>
        /// <param name="conditions">Conditions.</param>
        public RegBase Or(List<RelGroup> conditions)
        {
            if (conditions.Count < 2)
                throw new ArgumentException("Must have at least two subexpressions.");
            return new Or(conditions, this.Parent);
        }

        /// <summary>
        /// Performs an OR operation on two expression chains.
        /// </summary>
        /// <param name="first">First.</param>
        /// <param name="second">Second.</param>
        public RegBase Or(RelGroup first, RelGroup second)
        {
            return new Or(first, second, this.Parent);
        }

        /// <summary>
        /// Adds a subexpression to the end of the chain.
        /// </summary>
        /// <returns>The expression.</returns>
        /// <param name="subexpression">Subexpression.</param>
        public RegBase SubExpression(RelGroup subexpression)
        {
            return new SubExpression(subexpression, this.Parent);
        }


        #endregion

    }
}

